using System;
using System.Windows.Forms;
using BLGenerator.BusinessLogic;

namespace BLGenerator
{
    public partial class MainForm : Form
    {
        private BusinessLogic.Project _project;
        private string _filename;

        protected string Filename
        {
            get { return _filename; }
            set
            {
                _filename = value;
                BindTitle();
            }
        }

        public MainForm()
        {
            InitializeComponent();
            CreateProject();
            Filename = null;
            BindTitle();
        }

        #region Event handlers

        #region Menu

        #region File

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CloseProject())
            {
                CreateProject();
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CloseProject())
            {
                Open();
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save(false);
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save(true);
        }

        private void exitToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            if (CloseProject()) this.Close();
        }

        #endregion

        #region Project

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new ProjectSettingsForm(_project).ShowDialog();
        }

        private void refreshCatalogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Report report = _project.RefreshCatalog();
            if (report.Count == 0) return;
            MessageBox.Show(report.ToString(), "Refresh catalog result");
        }

        private void generateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _project.GenerateFiles();
        }

        #endregion

        #endregion

        private void tvEntities_AfterCheck(object sender, TreeViewEventArgs e)
        {
            Entity entity = (Entity) e.Node.Tag;
            entity.IsGenerated = e.Node.Checked;
        }

        private void tvEntities_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            string oldName = e.Node.Text;
            foreach (Entity entity in _project.EntityCollection)
                if (entity.EntityName == oldName)
                {
                    entity.EntityName = e.Label;
                    break;
                }
        }

        #endregion

        #region Helper methods

        /// <summary>Closes current project</summary>
        /// <returns>Returns true if project was closed</returns>
        protected bool CloseProject()
        {
            if (_project.IsModified)
            {
                DialogResult dialogResult =
                    MessageBox.Show("Project hasn't been saved. Would you like to save it now?", "Save?",
                                    MessageBoxButtons.YesNoCancel);
                if (dialogResult == DialogResult.Cancel) return false;
                else if (dialogResult == DialogResult.Yes)
                {
                    if (!Save(false)) return false;

                }
            }
            return true;
        }

        protected bool Open()
        {
            OpenFileDialog openFileDialog = (OpenFileDialog)CreateFileDialog(FileDialogType.Open);
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                CreateProject();
                Filename = openFileDialog.FileName;
            }
            else
                return false;
            _project.OpenProject(Filename);
            return true;
        }

        protected bool Save(bool forceChooseFile)
        {
            if (forceChooseFile || Filename == null)
            {
                SaveFileDialog saveFileDialog = (SaveFileDialog)CreateFileDialog(FileDialogType.Save);
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                    Filename = saveFileDialog.FileName;
                else
                    return false;
            }

            _project.SaveProject(Filename);

            return true;
        }

        protected void CreateProject()
        {
            _project = new Project();
            Filename = null;
            SetEventHandlers();
        }

        protected FileDialog CreateFileDialog(FileDialogType fileDialogType)
        {
            FileDialog fileDialog;
            if (fileDialogType == FileDialogType.Open)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.CheckFileExists = true;
                fileDialog = openFileDialog;
            }
            else
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.CreatePrompt = true;
                fileDialog = saveFileDialog;
                saveFileDialog.OverwritePrompt = true;
            }

            fileDialog.AddExtension = true;
            fileDialog.DefaultExt = "sblgp";
            if (Filename == null)
                fileDialog.InitialDirectory = Program.ApplicationPath + @"\Projects";
            else
                fileDialog.FileName = Filename;
            fileDialog.ValidateNames = true;
            fileDialog.Filter = "SnowBLGen projects (*.sblgp)|*.sblgp";
            fileDialog.FilterIndex = 0;
            return fileDialog;
        }

        protected void SetEventHandlers()
        {
            _project.EntityCollectionChanged += delegate { BindEntitiesTree(); };
            _project.IsModifiedChanged += delegate { BindTitle(); };
        }

        #endregion

        #region Binding methods

        protected void BindTitle()
        {
            string displayFileName = Filename == null
                                         ? "Untitled"
                                         : Filename.Substring(Filename.LastIndexOfAny(new char[] { '\\', '/' }) + 1);
            char displayIsModified = _project.IsModified ? '*' : ' ';
            this.Text = string.Format("SnowBLGenerator - {0} {1}", displayFileName, displayIsModified);
        }

        protected void BindEntitiesTree()
        {
            tvEntities.Nodes.Clear();
            tvEntities.SuspendLayout();
            foreach (Entity entity in _project.EntityCollection)
            {
                TreeNode entityNode = new TreeNode(entity.EntityName);
                foreach (Field field in entity.FieldCollection)
                {
                    entityNode.Nodes.Add(field.FieldName);
                }
                entityNode.Checked = entity.IsGenerated;
                entityNode.Tag = entity;
                tvEntities.Nodes.Add(entityNode);
                entityNode.Collapse();
            }
            tvEntities.ResumeLayout(true);
        }

        #endregion

        protected enum FileDialogType
        {
            Open,
            Save
        }

    }
}